/*
 * The main entry point for all demos.
 * 
 * Part of the Cyclone physics system.
 * 
 * Copyright (c) Icosagon 2003. All Rights Reserved.
 *
 * This software is distributed under licence. Use of this software
 * implies agreement with all terms and conditions of the accompanying
 * software licence.
 */

#include <gl/glfw.h>

// Include the general application structure.
#include "app.h"

// Include the timing functions
#include "timing.h"

// Forward declaration of the function that will return the 
// application object for this particular demo. This should be 
// implemented in the demo's .cpp file.
extern Application* getApplication();

// Store the global application object.
Application* app;

int window_width = 800, window_height = 600;

void init() {
	int window_width = 800, window_height = 600;
	float aspect_ratio = (float)window_width/window_height;

	// Initialise GLFW
	if( !glfwInit() ) {
		exit( EXIT_FAILURE );
	}

	// Open an OpenGL window
	if( !glfwOpenWindow( window_width, window_height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW ) ) {
		glfwTerminate();
		exit( EXIT_FAILURE );
	}

	glfwSetWindowTitle("Physics Coursework: Marcus Belcher 072004612");

	app = getApplication();
	TimingData::init();
	app->initGraphics();
	//glEnable(GL_TEXTURE_2D);
	//glEnable(GL_DEPTH_TEST);
	//glEnable(GL_LIGHTING); 
    //glEnable (GL_LIGHT0); 
    //glShadeModel (GL_SMOOTH); 
	//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(75.0, aspect_ratio, 1.0, 20000.0);

	glMatrixMode(GL_MODELVIEW);
}

//exits the game
void exit() {
	app->deinit();
    delete app;
    TimingData::deinit();

	// Close window and terminate GLFW
	glfwTerminate();

	// Exit program
	exit( EXIT_SUCCESS );
}

/**
 * Creates a window in which to display the scene.
 *
void createWindow(const char* title)
{
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(640,320);
    glutInitWindowPosition(0,0);
    glutCreateWindow(title);
}
*/
/**
 * Called each frame to update the 3D scene. Delegates to
 * the application.
 */
void update()
{
    // Update the timing.
    TimingData::get().update();

    // Delegate to the application.
    app->update();
}

/**
 * Called each frame to display the 3D scene. Delegates to
 * the application.
 */
void display()
{
    app->display();

    // Update the displayed content.
    glFlush();
    glfwSwapBuffers();
}

/**
 * Called when a key is pressed.
 */
void keyboard()
{
    // Note we omit passing on the x and y: they are rarely needed.
    app->key();
}

/**
 * The main entry point. We pass arguments onto GLUT.
 */
int main()
{
	int running = GL_TRUE;
	int game_end = 0;

	//initialize the openGL window
	init();

	//create a function to setup the world
	//current_game.CreateGameWorld();

	// Main loop
	while( running ) {
		
		//updates the world
		update();

		keyboard();

		//sets up the camera for the game
		//current_game.setup_camera();
		display();

		// Swap front and back rendering buffers
		//glfwSwapBuffers();

		// Check if ESC key	was pressed or window was closed
		running = !glfwGetKey( GLFW_KEY_ESC ) && glfwGetWindowParam( GLFW_OPENED );
	}

	//exit the openGL window
	exit();
	
	return 0;

	/*
    // Set up GLUT and the timers
    glutInit(&argc, argv);
    TimingData::init();

    // Create the application and its window
    app = getApplication();
    createWindow(app->getTitle());

    // Set up the appropriate handler functions
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutDisplayFunc(display);
    glutIdleFunc(update);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
   
    // Run the application
    app->initGraphics(); 
    glutMainLoop();

    // Clean up the application
    app->deinit();
    delete app;
    TimingData::deinit();
	*/
}